package com.bestillet.defaultmultishop;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.util.Log;

public class ShopApplication extends Application {
	private HashMap<String, ImageTask> tasks;
	private HashMap<String, Bitmap> images;
	
	private LruCache<String, Bitmap> cache;
	
	private ArrayList<Category> categories;
	private ArrayList<Card> cards;
	private ArrayList<Shop> shops;
	
	private Shop shop;
	
	private int kundeId, basketId;
	
	@Override
	public void onCreate() {
		super.onCreate();
		
		kundeId = 30;
		
		tasks = new HashMap<String, ImageTask>();
		images = new HashMap<String, Bitmap>();
		
		categories = new ArrayList<Category>();
		cards = new ArrayList<Card>();
		shops = new ArrayList<Shop>();
		
		final int max = (int) (Runtime.getRuntime().maxMemory() / 1024);
	    final int size = max / 8;
	    cache = new LruCache<String, Bitmap>(size) {
	        @SuppressLint("NewApi")
			@Override
	        protected int sizeOf(String key, Bitmap bitmap) {
	        	if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2)
	                return bitmap.getByteCount() / 1024;
	            else
	                return (bitmap.getRowBytes() * bitmap.getHeight()) / 1024;
	        }
	    };
	}

	public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
	    if (getBitmapFromMemCache(key) == null)
	        cache.put(key, bitmap);
	}
	
	public void removeBitmapFromMemoryCache(String key) {
		if (getBitmapFromMemCache(key) != null)
			cache.remove(key);
	}
	
	public Bitmap getBitmapFromMemCache(String key) {
	    return cache.get(key);
	}
	
	public Shop getShop() {
		return shop;
	}

	public void setShop(Shop shop) {
		this.shop = shop;
	}

	public int getKundeId() {
		return kundeId;
	}

	public void setKundeId(int kundeId) {
		this.kundeId = kundeId;
	}

	public int getBasketId() {
		return basketId;
	}

	public void setBasketId(int basketId) {
		this.basketId = basketId;
	}

	public ArrayList<Category> getCategories() {
		return new ArrayList<Category>(categories);
	}
	
	public void clearCategories() {
		categories.clear();
	}
	
	public void addCategories(ArrayList<Category> categories) {
		this.clearCategories();
		this.categories.addAll(categories);
	}

	public ArrayList<Shop> getShops() {
		return new ArrayList<Shop>(shops);
	}
	
	public void clearShops() {
		shops.clear();
	}
	
	public void addShops(ArrayList<Shop> shops) {
		this.shops.addAll(shops);
	}

	public ArrayList<Card> getCards() {
		return new ArrayList<Card>(cards);
	}
	
	public void clearCards() {
		cards.clear();
	}
	
	public void addCards(ArrayList<Card> cards) {
		this.cards.addAll(cards);
	}
	
	public Bitmap getImage(String key) {
		return images.get(key);
	}
	
	public void stopTasks() {
		for (ImageTask value : tasks.values())
			if (value != null)
				if (value.getStatus() == AsyncTask.Status.RUNNING)
					value.cancel(true);
		tasks.clear();
	}
	
	public void downloadImage(String picture, OnTaskCompleted callback, Activity activity) {
		if (!isImageCached(picture) && !isImageMapped(picture) && !tasks.containsKey(picture) && picture.length() > 0) {
			ImageTask task = new ImageTask();
			task.setCallback(callback);
			task.setActivity(activity);
			task.execute(picture);
			tasks.put(picture, task);
		}
	}
	
	private boolean isImageCached(String name) {
		Bitmap b = getBitmapFromMemCache(name);
		if (b != null) {
			if (!b.isRecycled())
				images.put(name, b);
			else
				removeBitmapFromMemoryCache(name);
			return !b.isRecycled();
		}
		return false;
	}
	
	private boolean isImageMapped(String name) {
		Bitmap b = images.get(name);
		if (b != null)
			return !b.isRecycled();
		return false;
	}
	
	private class ImageTask extends AsyncTask<String, Void, Boolean> {
		private OnTaskCompleted callback;
		private Activity activity;
		
    	@Override
		protected Boolean doInBackground(String... params) {
    		try {
    			InputStream in = Server.get(Server.PRODUCT_IMAGES + params[0]);
    			Bitmap b = Server.downloadBitmap(in, activity);
    			in.close();
				images.put(params[0], b);
    			addBitmapToMemoryCache(params[0], b);
			} catch (IOException e) {
    			Log.e("Shop", "IOException: " + e.getMessage());
				return false;
			} catch (NullPointerException e) {
    			Log.e("Shop", "NullPointerException: " + e.getMessage());
				return false;
			} catch (OutOfMemoryError e) {
    			Log.e("Shop", "OutOfMemoryError: " + e.getMessage());
				return false;
			}
    		return true;
    	}
    
	    @Override
	    protected void onPostExecute(Boolean success) {
			tasks.remove(this);
			callback.onTaskCompleted(success);
	    }
	    
	    public void setCallback(OnTaskCompleted callback) {
	    	this.callback = callback;
	    }
	    
	    public void setActivity(Activity activity) {
	    	this.activity = activity;
	    }
	}
}